import java.util.LinkedList;

public abstract class Node {
    //pre point
    int pre_i = -1;
    int pre_j = -1;
    int[][] board = new int[3][3];
    LinkedList<Node> childNodes = null;
    Node nextNode = null;
    Integer _F = null;
    Boolean isWin = null;
    Boolean isFull = null;
    int values[] = null;

    /*调整估值函数，增加对必杀局面的判断
    * */
    public void evaluateF() {
        if (isFull()) {
            _F = 0;
            return;
        }
        int p1 = 0, p2 = 0;
        //row
        for (int i = 0; i < 3; i++) {
            if (board[i][0] != -1 && board[i][1] != -1 && board[i][2] != -1) {
                p1++;
            }
            if (board[i][0] != 1 && board[i][1] != 1 && board[i][2] != 1) p2++;
        }
        //column
        for (int i = 0; i < 3; i++) {
            if (board[0][i] != -1 && board[1][i] != -1 && board[2][i] != -1) p1++;
            if (board[0][i] != 1 && board[1][i] != 1 && board[2][i] != 1) p2++;
        }
        //diagonal
        if (board[0][0] != -1 && board[1][1] != -1 && board[2][2] != -1) p1++;
        if (board[0][0] != 1 && board[1][1] != 1 && board[2][2] != 1) p2++;

        if (board[2][0] != -1 && board[1][1] != -1 && board[0][2] != -1) p1++;
        if (board[2][0] != 1 && board[1][1] != 1 && board[0][2] != 1) p2++;

        _F = p1 - p2;
    }

    Node getNextNode() {
        return nextNode;
    }

    Node getNextNodeByPre(int pre_i, int pre_j) {
        if (childNodes == null) {
            extend();
        }
        for (Node node : childNodes) {
            if (node.pre_i == pre_i && node.pre_j == pre_j) return node;
        }
        return null;
    }

    void printBoard(int board[][]) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("-------------------");
    }

    //set F
    abstract void predictDeath();

    boolean isFull() {
        if (isFull != null) return isFull;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == 0) return isFull = false;
            }
        }
        return isFull = true;
    }

    /*判断 绝对 胜利，即三点一线
    * */
    boolean isWin() {
        if (isWin != null) return isWin;
        for (int value : getValues()) {
            if (Math.abs(value) == 3) return isWin = true;
        }
        return isWin = false;
    }

    //获取values数组
    public int[] getValues() {
        if (values == null) calculateValues();
        return values;
    }

    //计算行、列、对角线的和
    void calculateValues() {
        if (values != null) return;
        values = new int[8];
        for (int i = 0; i < 3; i++) {
            values[i] = board[i][0] + board[i][1] + board[i][2];
        }
        //column
        for (int i = 0; i < 3; i++) {
            values[i + 3] = board[0][i] + board[1][i] + board[2][i];
        }
        //diagonal
        values[6] = board[0][0] + board[1][1] + board[2][2];
        values[7] = board[2][0] + board[1][1] + board[0][2];
    }

    void reset() {
        nextNode = null;
        _F = null;
    }

    //得到已放棋子的个数
    int getChessCount() {
        int count = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] != 0) count++;
            }
        }
        return count;
    }

    //分别获取关键步的计数
    int getPlayerVitalCount() {
        int count = 0;
        for (int value : getValues()) {
            if (value == 2) count++;
        }
        return count;
    }

    int getComputerVitalCount() {
        int count = 0;
        for (int value : getValues()) {
            if (value == -2) count++;
        }
        return count;
    }

    abstract void play(int depth, int parentAlpha, int parentBate);

    abstract void extend();
}